/*
 * Copyright 2014 alexpad@gmail.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package alexpad.util;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.io.IOUtils;

/**
 *
 * @author alexpad@gmail.com
 */
public class ConfigHelper {
	
	private final SimpleDateFormat sdf = new SimpleDateFormat();
	private final Properties properties;
	private File file;

	protected ConfigHelper(String filePath) {
		this.file = new File(filePath);
		properties = new Properties();
	}
	
	protected ConfigHelper(File file) {
		this.file = file;
		properties = new Properties();
	}
	
	protected ConfigHelper(Properties properties) {
		this.properties = properties;
	}
	
	protected ConfigHelper() {
		properties = new Properties();
	}

	public void load() throws IOException {
		FileInputStream fis = null;
		try{
			fis = new FileInputStream(file);
			properties.load(fis);
		}
		finally{
			if(fis!=null){
				IOUtils.closeQuietly(fis);
			}
		}
	}
	
	public boolean isWritableToFile(){
		return file!=null && file.isFile() && file.canWrite();
	}
	
	
	public void save() throws IOException {
		save(null);
	}
	
	public void save(String comments) throws IOException {
		FileOutputStream fos = null;
		if(file==null){
			throw new IllegalStateException("file reference is null");
		}
		try {
			fos = new FileOutputStream(file);
			properties.store(fos, comments);
		}
		finally {
			IOUtils.closeQuietly(fos);
		}
	}
	
	public void exportProperties(File exportFile, String comments) throws IOException {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(exportFile);
			properties.store(fos, comments);
		}
		finally {
			IOUtils.closeQuietly(fos);
		}
	}
	
	public boolean isEmpty(){
		return properties.isEmpty();
	}
	
	public String getProperty(String keyName) {
		return properties.getProperty(keyName);
	}

	public String getProperty(String keyName, String defaultValue) {
		return properties.getProperty(keyName, defaultValue);
	}

	public int getProperty(String keyName, int defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}
	
	public Integer getProperty(String keyName, Integer defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}

	public long getProperty(String keyName, long defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}

	public float getProperty(String keyName, float defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}

	public double getProperty(String keyName, double defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}

	public boolean getProperty(String keyName, boolean defaultValue) {
		return StringUtil.changeBlank(properties.getProperty(keyName), defaultValue);
	}

	public Date getProperty(String keyName, String pattern, Date defaultDate) {
		Date value = null;
		try{
			synchronized(sdf){
				sdf.applyPattern(pattern);
				value = sdf.parse(properties.getProperty(keyName));
			}	
		}
		catch(Throwable t){
		}
		if(value==null) return defaultDate;
		return value;
	}

	public String[] getValues(String keyName, String delimiter) {
		String value = properties.getProperty(keyName);
		if(value!=null){
			StringTokenizer st = new StringTokenizer(value, delimiter);
			String[] values = new String[st.countTokens()];
			for (int n=0; n<st.countTokens(); n++) {
				values[n] = st.nextToken();
			}
			return values;
		}
		else return new String[0];
	}

	public ConfigHelper getSubPropertiesTrimmingKeyPrefix(String keyNamePrefix) {
		Properties subProperties = new Properties();

		Set entries = properties.entrySet();
		Iterator<Map.Entry<String, String>> iter = entries.iterator();
		Map.Entry<String, String> entry;
		if(!keyNamePrefix.endsWith(".")) keyNamePrefix = keyNamePrefix + ".";
		while (iter.hasNext()) {
			entry = iter.next();
			if (entry.getKey().startsWith(keyNamePrefix)) {
				subProperties.setProperty(entry.getKey().substring(keyNamePrefix.length()), entry.getValue());
			}
		}
		return new ConfigHelper(subProperties);
	}
	
	public void setProperty(String keyName, String value){
		properties.setProperty(keyName, value);
	}
	
	public void setProperty(String keyName, int value){
		properties.setProperty(keyName, String.valueOf(value));
	}
}
